/*
 *    Copyright (c) 2018-2025, tdf All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: tdf
 */

package com.engine4cloud.tdf.common.security.service;

import com.engine4cloud.tdf.admin.api.dto.UserInfo;
import com.engine4cloud.tdf.admin.api.feign.RemoteUserService;
import com.engine4cloud.tdf.common.core.constant.CacheConstants;
import com.engine4cloud.tdf.common.core.constant.SecurityConstants;
import com.engine4cloud.tdf.common.core.constant.enums.UserTypeEnum;
import com.engine4cloud.tdf.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Primary;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * 用户详细信息 default
 *
 * @author tdf
 */
@Slf4j
@Primary
@RequiredArgsConstructor
public class TdfDefaultUserDetailsServiceImpl implements TdfUserDetailsService {

    private final RemoteUserService remoteUserService;

    private final CacheManager cacheManager;

    /**
     * 用户密码登录
     *
     * @param username 用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    @SneakyThrows
    public UserDetails loadUserByUsername(String username) {
        Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
        if (cache != null && cache.get(username) != null) {
            return cache.get(username, TdfUser.class);
        }

        R<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
        UserDetails userDetails = getUserDetails(result);
        cache.put(username, userDetails);
        return userDetails;
    }

    /**
     * 通过用户实体查询
     *
     * @param tdfUser user
     * @return
     */
    @Override
    public UserDetails loadUserByUser(TdfUser tdfUser) {
        // 避免 C端用户通过接口调用B端接口的安全问题
        if (UserTypeEnum.TOB.getStatus().equals(tdfUser.getUserType())) {
            return loadUserByUsername(tdfUser.getUsername());
        }
        return null;
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE;
    }

}
